#include "transmission/tcp_client.h"
#include "transmission/tcp_common.h"
#include "log.h"

#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

void* tcp_client_thread(void* arg)
{
    tcp_client_t* client = (tcp_client_t*)arg;
    if (client == NULL) {
        LOG_ERROR("client is null");
        return NULL;
    }
    // 主循环，接收要传输的数据
    while (g_transmission_running_flag) {
        // 等待上层用户开始传输，进行唤醒
        pthread_cond_wait(&(client->cond), &(client->mutex));
        // 先出队一个数据
        message_t* msg = message_dequeue(client->queue_wait_for_send);
        int bytes_wait_for_send = 0;
        int bytes_received = 0;
        while (msg != NULL) {
            // 发送
            bytes_wait_for_send = msg->data_bytes + sizeof(int);
            tcp_safe_write(client->fd, &bytes_wait_for_send, sizeof(int));
            tcp_safe_write(client->fd, msg->data, msg->data_bytes);
            // 确认server收到的数据量
            tcp_safe_read(client->fd, &bytes_received, sizeof(int));
            if (bytes_received != bytes_wait_for_send) {
                LOG_ERROR("bytes_received != bytes_wait_for_send");
                break;
            }
            msg = message_dequeue(client->queue_wait_for_send);
        }
    }

    // TODO:
    return NULL;
}

tcp_client_t* tcp_client_create(tcp_client_config_t* config)
{
    tcp_client_t* client = (tcp_client_t*)malloc(sizeof(tcp_client_t));
    if (client == NULL)
    {
        LOG_ERROR("malloc for client failed");
        return NULL;
    }
    (void)memset(client, 0, sizeof(tcp_client_t));

    client->config = config;
    client->fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client->fd < 0) {
        LOG_ERROR("create socket failed");
        goto TAG_TCP_CLIENT_CREAT_FAILED;
    }
    struct sockaddr_in server_addr;//需要连接的服务器地址信息
    //填充服务器地址信息
    server_addr.sin_family 	= AF_INET; //网络层的IP协议: IPV4
    server_addr.sin_port 		= htons(config->port); //传输层的端口号
    server_addr.sin_addr.s_addr   = inet_addr(config->ip); //网络层的IP地址: 实际的服务器IP地址
    bzero(&(server_addr.sin_zero), 8); //保留的8字节置零
    // 发起握手请求
    if(connect(client->fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) {
        LOG_ERROR("connect failed");
        goto TAG_TCP_CLIENT_CREAT_FAILED;
    }
    client->queue_wait_for_send = message_queue_create(config->queue_size);
    if (client->queue_wait_for_send == NULL) {
        LOG_ERROR("create message queue failed");
        goto TAG_TCP_CLIENT_CREAT_FAILED;
    }

    pthread_mutex_init(&(client->mutex), NULL);
    pthread_cond_init(&(client->cond), NULL);

    pthread_create(&(client->thread), NULL, tcp_client_thread, (void*)client);
    pthread_detach(client->thread);

    return client;

TAG_TCP_CLIENT_CREAT_FAILED:
    return NULL;
}